<?php

namespace App\Http\Controllers\Api;


use App\Http\Controllers\Controller;
use App\Models\ZZMed\ZHospMember;
use App\Models\ZPituitaryPatientsNotice;
use App\Models\ZPituitaryPatientsTag;
use App\Models\ZPituitaryTags;
use App\Models\ZPituitaryUserContactRecords;
use App\Models\ZZMed\ZUser;
use App\Services\VisitRemindService;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

/**
 *  随访管理提醒控制器
 * Class NoticeVisitsController
 * @package App\Http\Controllers\Api
 */
class NoticeVisitsController extends Controller
{


    /**
     *  随访提醒/漏诊
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \App\Exceptions\AuthException
     */
    public function getFollowManageList(Request $request)
    {

        $params = $request->all();

        if (!isset($params['hosp_id']) || empty($params['hosp_id']) || !isset($params['dept_id']) || empty($params['dept_id'])) {
            return $this->error(-10001, "医院/科室ID不能为空");
        }

        $user = $this->authUser();
        $user->dept_id = ZHospMember::getDocDeptId($user->id);
        if (!isset($user->hosp_id) || !isset($user->dept_id)) {
            return $this->error(-10002, "用户数据错误");
        }

        if ($params['hosp_id'] != $user->hosp_id || $params['dept_id'] != $user->dept_id) {
            return $this->error(-10003, "您没有该医院的权限");
        }

        $size = $params['page_size'] ?? 10;
        $page = isset($params['page_no']) && !empty($params['page_no']) ? $params['page_no'] - 1 : 0;
        $type = $params['type'] ?? 1;//1 就诊 2 漏诊
        $hospId = $params['hosp_id'];
        $deptId = $params['dept_id'];
        $barcode = $params['barcode'] ?? '';
        $cell = $params['cell'] ?? '';
        $name = $params['name'] ?? '';

        $source = $params['source'] ?? 0;//0 mmc中心的列表  1是随访提醒中的列表 2 是近期


        $searchUserIds = [];
        if ($barcode || $name || $cell){
           $searchArr =  ZUser::query()->from('z_user as u')->selectRaw('id')
                ->when($barcode, function ($query) use ($barcode) {
                    return $query->where('u.barcode', $barcode);
                })
                ->when($name, function ($query) use ($name) {
                    return $query->where('u.name', $name);
                })
                ->when($cell, function ($query) use ($cell) {
                    return $query->where('u.cell', $cell);
                })->get()->toArray();

           $searchUserIds = array_column($searchArr,'id');

           $searchUserIds = $searchUserIds ? $searchUserIds : [1];

        }

        $query = ZPituitaryPatientsNotice::query()->from('z_pituitary_patients_notice as z')
            ->selectRaw('z.id,z.user_id,z.hosp_id,z.visit_level,z.visit_at,z.visit,z.remaining_days,z.overlap_days,z.first_visit_at,z.newest_visit_at,z.actual_reserva,z.type,z.state,z.next_followup,z.newest_visit_level,z.count_down,z.is_remind')
            ->where('z.hosp_id', $hospId)
            ->where('z.dept_id', $deptId)
            ->when($searchUserIds,  function ($query) use ($searchUserIds) {
                return $query->whereIn('z.user_id', $searchUserIds);
            });

        //下次随访日期
        if (isset($params['next_followup_start']) && !empty($params['next_followup_start'])) {
            $query->where('z.next_followup', '>=', $params['next_followup_start']);
        }
        if (isset($params['next_followup_end']) && !empty($params['next_followup_end'])) {
            $query->where('z.next_followup', '<=', $params['next_followup_end']);
        }

        //标签
        if (isset($params['tip']) && !empty($params['tip'])) {
            if (!is_array($params['tip'])) {
                $params['tip'] = explode(',', $params['tip']);
            }
            $userIds = array_column(ZPituitaryPatientsTag::getUserByTags($hospId, $deptId, $params['tip']), 'patient_id');

            $query->whereIn("z.user_id", $userIds);

        }

        // 总数
        $count = $query->count();

        // 漏诊人数
        $overlap = ZPituitaryPatientsNotice::getOverlaps($hospId, $deptId, $source);

        $hospRetPage = ceil($count / $size);
        if ($hospRetPage < $page) {
            $page = $hospRetPage;
        }
        $offset = $page * $size;

        //排序
        $order = "z.is_remind desc,z.state asc,z.type asc,z.count_down asc,z.remaining_days asc,z.id asc";
        if ($type == 2) {
            $order = "z.is_remind desc,z.state asc,z.count_down asc,z.overlap_days desc,z.id asc";
        }

        $list = $query->orderByRaw($order)
            ->offset($offset)
            ->limit($size)
            ->get();
        $return = [
            'current_page' => 1,
            'total' => 0,
            'data' => [],
            'overlap' => $overlap,
        ];

        if (!empty($list)) {
            $managePlan = $this->getManagePlan($params['hosp_id'], $params['dept_id'], $source);
            //获取本医院所有的标签
            $tips = $managePlan['tips'] ?? [];
            //获取本医院全部的随访计划
            $plan = $managePlan['plan'] ?? [];
            //获取本医院所有的管理方案
            $manage = $managePlan['manage'] ?? [];
            $now = date("Y-m-d H:i:s", time());
            $userIds = [];
            foreach ($list as &$item) {
                $userIds[] = $item->user_id;
                $item->age = getBday($item->bday);

                //处理时间
                $item->visit_at = $item->visit_at > '0001-01-01' ? $item->visit_at : '';
                $item->first_visit_at = $item->first_visit_at > '0001-01-01' ? $item->first_visit_at : '';
                $item->newest_visit_at = $item->newest_visit_at > '0001-01-01' ? $item->newest_visit_at : '';
                $item->actual_reserva = $item->actual_reserva > '0001-01-01' ? $item->actual_reserva : '';
                $item->next_followup = $item->next_followup > '0001-01-01' ? $item->next_followup : '';
                $item->count_down = $item->count_down >= $now ? $this->time2string($item->count_down) : '';
                $item->remaining_days = $item->is_remind == 0 ? "" : $item->remaining_days;
                $item->overlap_days = $item->is_remind == 0 ? "" : $item->overlap_days;

                //随访计划
//                $item->plan_name = !empty($plan) ? ($plan[$item->plan_id] ?? 'MMC全部访视') : 'MMC全部访视';
                //管理方案
//                $item->manage_name = !empty($manage) ? ($manage[$item->manage_id] ?? 'MMC中心业务') : 'MMC中心业务';
            }

            // 处理用户的标签
            $userTags = [];
            $res = ZPituitaryPatientsTag::getUserTags($userIds, $hospId, $deptId);
            foreach ($res as $item) {
                $userTags[$item['user_id']][] = $item['name'];
            }

            foreach ($list as &$ite) {
                $ite->tip_name = $userTags[$ite->user_id] ?? [];
            }

            // 处理用户基本信息  == 如跨库 需要单独查询用户数据
            $userBaseInfoArr =  ZUser::query()->selectRaw('id as user_id,name,sex,bday,barcode,cell')
                ->whereIn('id', $userIds)
                ->get()->toArray();
            $baseInfoArr = [];
            foreach ($userBaseInfoArr as $one){
                $baseInfoArr[$one['user_id']] = $one;
            }
            foreach ($list as &$items) {
                $items->name = $baseInfoArr[$items->user_id]['name'] ?? '';
                $items->sex = $baseInfoArr[$items->user_id]['sex'] ?? '';
                $items->bday = $baseInfoArr[$items->user_id]['bday'] ?? '';
                $items->barcode = $baseInfoArr[$items->user_id]['barcode'] ?? '';
                $items->cell = $baseInfoArr[$items->user_id]['cell'] ?? '';
            }

            $return = [
                'current_page' => $page,
                'total' => $count,
                'data' => $list,
                'overlap' => $overlap,
            ];
        }

        return $this->success($return);

    }



    /**
     *  获取短信
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     */
    public function getHospitalCustomSmsTemplate(Request $request)
    {
        $data = $request->all();
        $validate = Validator::make($data, [
            'hospital_id' => 'required',
            'department_id' => 'required'
        ]);
        if ($validate->fails()) {
            return $this->error(42200, "参数异常");
        }

        $list = VisitRemindService::getSmsTemplates($data["hospital_id"], $data["department_id"]);
        return $this->success($list);
    }


    /**
     *  发送随访自定义短信
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function saveSmsNotice(Request $request)
    {

        $rules = [
            'user_ids' => 'required',
            'visit_levels' => 'required',
            'cells' => 'required',
            'hosp_id' => 'required',
            'dept_id' => 'required',
            'doc_id' => 'required',
            'template_type' => 'required',
        ];
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            return $this->error(42200);
        }
        $params = $request->all();

        $userIds = isset($params["user_ids"]) && $params["user_ids"] ? $params["user_ids"] : "";
        $visitLevels = isset($params["visit_levels"]) && $params["visit_levels"] ? $params["visit_levels"] : "";
        $cells = isset($params["cells"]) && $params["cells"] ? $params["cells"] : "";
        $params["hosp_id"] = isset($params["hosp_id"]) && $params["hosp_id"] ? $params["hosp_id"] : 0;
        $params["dept_id"] = isset($params["dept_id"]) && $params["dept_id"] ? $params["dept_id"] : 0;
        $params["doc_id"] = isset($params["doc_id"]) && $params["doc_id"] ? $params["doc_id"] : 0;
        $params["status"] = 1;
        $params["from_flg"] = 1;
        $params["remind_day"] = 0;
        $params["remind_time"] = 0;
        $params["remind_date"] = "0001-01-01 00:00:00";
        $params["remark"] = "";
        $params["created_at"] = date("Y-m-d H:i:s");
        $params["updated_at"] = date("Y-m-d H:i:s");
        $hosp_name = isset($params["hosp_name"]) && $params["hosp_name"] ? $params["hosp_name"] : "";
        $userIdsArr = explode(",", trim($userIds, ","));
        $visitLevelsArr = explode(",", trim($visitLevels, ","));
        $cellsArr = explode(",", trim($cells, ","));
        $teplateCode = isset($params["template_type"]) && $params["template_type"] ? $params["template_type"] : '502';

        // 获取短信内容，用于联系备注
        $smsContent = ZUser::query()
                ->from('sms_template_config')
                ->where('type', $teplateCode)
                ->first()->content ?? '';
        $smsContent = str_replace("#hospname#", $hosp_name, $smsContent);
        try {
            foreach ($cellsArr as $k => $cell) {
                $params["user_id"] = $userIdsArr[$k];
                $params["visit_level"] = $visitLevelsArr[$k];
                $params['remark'] = $smsContent;
                $insertId = ZPituitaryUserContactRecords::saveRecord($params);
                //更新关联表
                $user_id = $params["user_id"];
                $visit_level = $params["visit_level"];
                $hosp_id = $params["hosp_id"];
                $dept_id = $params["dept_id"];
                $sql_notice = "update z_pituitary_patients_notice set state = '1',sms_times =  sms_times +1 ,count_down = '0001-01-01 00:00:00'  where hosp_id = '$hosp_id' and dept_id= '$dept_id' and newest_visit_level = '$visit_level'   and user_id  = '$user_id' ";

                DB::update($sql_notice);
            }

            //发送短信 担心失败会导致记录生成不了 单独处理
            foreach ($cellsArr as $k => $cell) {
                $this->smsNotice($cell, $hosp_name, $teplateCode);
            }
        } catch (\Exception $exc) {
            Log::error("执行报错" . $exc->getMessage() . $exc->getLine() . $exc->getTraceAsString() );
        }

        return $this->success([]);
    }


    /**
     *   短信发送
     * @param $cell
     * @param $hosp_name
     * @param string $typeId
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    function smsNotice($cell, $hosp_name, $typeId = '502')
    {

        //发送短信
        $params = [
            "phone" => $cell,
            "signName" => "智众医疗",
            "templateType" => $typeId,
            "templateParam" => [
                "hospname" => $hosp_name,
            ]
        ];
        $params['sign'] = $this->getSign($params);

        $httpClient = new Client();
        $uri = config('common-api.host') . config('common-api.sms.send.uri');
        try {
            $res = $httpClient->request('POST', $uri, ['json' => $params]);
            if ($res->getStatusCode() === 200) {
                $result = json_decode($res->getBody(), true);
                if ($result['status'] != 200) {
                    Log::error('短信验证码发送失败:', $result);
                    return false;
                }
            }
        } catch (GuzzleException $e) {
            Log::error($e->getMessage(), [$e->getCode(), $e->getTrace()]);
            return false;
        }

        return true;
    }


    /**
     *  获取联系记录
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     */
    public function getUserContactRecordList(Request $request)
    {
        $rules = [
            'user_id' => 'required',
            'hosp_id' => 'required',
            'dept_id' => 'required',
        ];
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            return $this->error(42200);
        }
        $params = $request->all();
        $userId = isset($params["user_id"]) && $params["user_id"] ? $params["user_id"] : 0;
        $hospId = isset($params["hosp_id"]) && $params["hosp_id"] ? $params["hosp_id"] : 0;
        $deptId = isset($params["dept_id"]) && $params["dept_id"] ? $params["dept_id"] : 0;
        $page_no = isset($params["page_no"]) && $params["page_no"] >= 1 ? $params["page_no"] - 1 : 0;
        $page_size = isset($params["page_size"]) && $params["page_size"] ? $params["page_size"] : 10;


        $query = ZPituitaryUserContactRecords::query()->from('z_pituitary_user_contact_records as pr')
            ->selectRaw('pr.*')
            ->where('pr.user_id', $userId)
            ->where('pr.hosp_id', $hospId)
            ->where('pr.dept_id', $deptId);

        $retPageCnt = $query->count();

        $ret = $query->forPage($page_no, $page_size)
            ->orderByDesc('pr.id')
            ->get()->toArray();

        $docIds = collect($ret)->pluck('doc_id')->toArray();
        $docNames = array_column(ZHospMember::query()->selectRaw('id,name')->whereIn('id', $docIds)->get()->toArray(),'name','id');

        foreach ($ret as $k => $v){
            $ret[$k]['name'] = $docNames[$v['doc_id']] ?? '';
        }

        return $this->success([
            "data" => $ret,
            "total" => $retPageCnt,
        ]);

    }

    /**
     *  保存联系记录
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \App\Exceptions\AuthException
     */
    public function saveUserContactRecord(Request $request)
    {

        $doctor = $this->authUser();
        $rules = [
            'user_id' => 'required',
            'visit_level' => 'required',
            'hosp_id' => 'required',
            'dept_id' => 'required',
            'is_remind' => 'required',
            // 'next_followup' => 'required', //下次随访时间
            'status' => 'required', //是否联系到
        ];
        $validator = Validator::make($request->all(), $rules);

        //验证是否预约
        $params = $request->all();

        $params['operator_id'] = $doctor->id;
        if ($validator->fails()) {
            if (isset($params["is_remind"]) && $params["is_remind"] == 1) {
                if (!isset($params["next_followup"])) {
                    return $this->error(42200, "下次随访不能为空");
                } else if (isset($params["next_followup"]) && !$params["next_followup"]) {
                    return $this->error(42200, "下次随访不能为空");
                }
            }
            return $this->error(42200,"参数错误");
        }

        //保存记录
        $params["user_id"] = isset($params["user_id"]) && $params["user_id"] ? $params["user_id"] : 0;
        $params["visit_level"] = isset($params["visit_level"]) && $params["visit_level"] ? $params["visit_level"] : 0;
        $params["hosp_id"] = isset($params["hosp_id"]) && $params["hosp_id"] ? $params["hosp_id"] : 0;
        $params["dept_id"] = isset($params["dept_id"]) && $params["dept_id"] ? $params["dept_id"] : 0;
        $params["doc_id"] = isset($params["operator_id"]) && $params["operator_id"] ? $params["operator_id"] : 0;
        $params["status"] = isset($params["status"]) && $params["status"] ? $params["status"] : 0;
        $params["from_flg"] = isset($params["from_flg"]) && $params["from_flg"] ? $params["from_flg"] : "0";
        $params["next_followup"] = isset($params["next_followup"]) && $params["next_followup"] ? $params["next_followup"] : "0001-01-01";

        $params["remind_day"] = isset($params["remind_day"]) && $params["remind_day"] ? $params["remind_day"] : "0";
        $params["remind_time"] = isset($params["remind_time"]) && $params["remind_time"] ? $params["remind_time"] : 0;
        $params["remind_date"] = "0001-01-01 00:00:00";


        $params["remark"] = isset($params["remark"]) && $params["remark"] ? $params["remark"] : "";
        $params["created_at"] = date("Y-m-d H:i:s");
        $params["updated_at"] = date("Y-m-d H:i:s");

        if ($params["status"] == 1) {
            $params["remind_day"] = 0;
            $params["remind_time"] = 0;
        } else {
            $params["remind_date"] = date("Y-m-d H:i:s", ($params["remind_day"] * 24 + $params["remind_time"]) * 3600 + time());
        }

        $insertId = ZPituitaryUserContactRecords::saveRecord($params);
        if ($params["remind_date"] < date("Y-m-d H:i:s")) {
            $params["remind_date"] = '0001-01-01 00:00:00';
        }

        $state = $params["status"];
        $user_id = $params["user_id"];
        $visit_level = $params["visit_level"];
        $hosp_id = $params["hosp_id"];
        $dept_id = $params["dept_id"];
        $next_followup = $params["next_followup"];
        $count_down = $params["remind_date"];

        $notice_detail = ZPituitaryPatientsNotice::query()->where('hosp_id', $hosp_id)
            ->where('dept_id', $dept_id)
            ->where('newest_visit_level', $visit_level)
            ->where('user_id', $user_id)
            ->first();

        if ($notice_detail) {
            $notice_detail->update([
                'state' => $state,
                'next_followup' => $next_followup,
                'count_down' => $count_down
            ]);
        }


        //更新相差日期
        if ($next_followup && $next_followup != "0001-01-01") {
            if ($notice_detail) {
                $actual_reserva = isset($notice_detail->actual_reserva) && $notice_detail->actual_reserva >= date("Y-m-d") ? $notice_detail->actual_reserva : "0001-01-01";
                if ($actual_reserva != "0001-01-01") {
                    $visitNextDate = $actual_reserva;
                } else {
                    $visitNextDate = $next_followup;
                }
                $remaining_days = (strtotime($visitNextDate) - strtotime(date("Y-m-d"))) / 86400;

                $notice_detail->update(['remaining_days' => $remaining_days, 'overlap_days' => -1, 'type' => 1]);

            }
        }

        return $this->success($insertId);
    }

    /**
     * 时间转字符串
     * @param $date
     * @return string
     */
    function time2string($date)
    {
        $second = strtotime($date) - time();
        $day = floor($second / (3600 * 24));
        $second = $second % (3600 * 24); //除去整天之后剩余的时间
        $hour = floor($second / 3600);
        $second = $second % 3600;
        $minute = floor($second / 60);
        $content = "";

        //超过1天
        if ($day > 0) {
            $content = $day . '天' . $hour . '小时' . $minute . "分";
        } else {
            if ($hour > 0) {
                $content = $hour . "小时后提醒";
            } else if ($minute > 0) {
                $content = "1小时内提醒";
            }
        }

        return $content;
    }

    /**
     *  获取下一个用户
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function getUserNext(Request $request)
    {

        $params = $request->all();

        if (!isset($params['hosp_id']) || empty($params['hosp_id']) || !isset($params['dept_id']) || empty($params['dept_id'])) {
            return $this->error(-10001, "医院/科室ID不能为空");
        }
        $hospId = $params['hosp_id'];
        $deptId = $params['dept_id'];


        $type = $params['type'] ?? 1;//1 就诊 2 漏诊
        $currentId = $params['current_id'] ?? 0;
        $source = $params['source'] ?? 0;

        $query = ZPituitaryPatientsNotice::query()->from('z_pituitary_patients_notice as z')
            ->selectRaw('z.id,z.user_id,z.hosp_id,z.visit_level,z.visit_at,z.visit,z.remaining_days,z.overlap_days,z.first_visit_at,z.newest_visit_at,z.actual_reserva,z.type,z.state,z.next_followup,z.newest_visit_level,z.count_down,z.is_remind')
            ->where('z.hosp_id', $hospId)
            ->where('z.dept_id', $deptId)
            ->where('z.id','>',$currentId);

            //排序
        $order = "z.is_remind desc,z.state asc,z.type asc,z.count_down asc,z.remaining_days asc,z.id asc";
        if ($type == 2) {
            $order = "z.is_remind desc,z.state asc,z.count_down asc,z.overlap_days desc,z.id asc";
        }

        $list = $query->orderByRaw($order)
            ->first();

        if (!empty($list)) {
            $data = $list->toArray();
            $data['source'] = $source;
            return $this->success($data);
        }

        return $this->error(-10002, "无下一个用户");

    }


    /**
     * 获取标签/随访/管理方案
     * @param $hospId
     * @param $deptId
     * @param int $source
     * @return array
     */
    public function getManagePlan($hospId, $deptId, $source = 0)
    {
        //获取本医院所有的标签
        $tags = ZPituitaryTags::getTags($hospId, $deptId);
        $tips = array_column($tags, 'name', 'id');
        $plan = [];
        $manage = [];
        return ['tips' => $tips, 'plan' => $plan, 'manage' => $manage];
    }

}